<script setup lang="ts">
import type { BubbleListProps, MessageInfo, PromptsProps } from 'ant-design-x-vue'
import type { VNode } from 'vue'
import {
  CommentOutlined,
  EllipsisOutlined,
  FireOutlined,
  HeartOutlined,
  ReadOutlined,
  ShareAltOutlined,
  SmileOutlined,
} from '@ant-design/icons-vue'
import { Button, Space, theme } from 'ant-design-vue'
import {
  Bubble,
  Prompts,
  Welcome,
} from 'ant-design-x-vue'
import { computed, h } from 'vue'
import ChatInput from './ChatInput.vue'

export interface Message  {
  id: string | number
  message: string
  status: 'loading' | 'local' | 'success',
  agent?: string,
}

interface Props {
  messages: MessageInfo<Message>[]
  // message: MessageInfo<string>[],
  content: string
  loading?: boolean
}

interface Emits {
  submit: [content: string]
  change: [value: string]
  promptClick: [description: string]
}

const props = withDefaults(defineProps<Props>(), {
  loading: false
})

const emit = defineEmits<Emits>()

const { token } = theme.useToken()

const styles = computed(() => {
  return {
    chat: {
      'height': '100%',
      'width': '100%',
      'max-width': '700px',
      'margin': '0 auto',
      'box-sizing': 'border-box',
      'display': 'flex',
      'flex-direction': 'column',
      'padding': `${token.value.paddingLG}px`,
      'gap': '16px',
    },
    messages: {
      flex: 1,
    },
    placeholder: {
      'padding-top': '32px',
      'text-align': 'left',
      'flex': 1,
    },
  } as const
})

function renderTitle(icon: VNode, title: string) {
  return h(Space, { align: 'start' }, () => [icon, h('span', title)])
}

const placeholderPromptsItems: PromptsProps['items'] = [
  {
    key: '1',
    label: renderTitle(h(FireOutlined, { style: { color: '#FF4D4F' } }), 'Hot Topics'),
    description: 'What are you interested in?',
    children: [
      {
        key: '1-1',
        description: `What's new in X?`,
      },
      {
        key: '1-2',
        description: `What's AGI?`,
      },
      {
        key: '1-3',
        description: `Where is the doc?`,
      },
    ],
  },
  {
    key: '2',
    label: renderTitle(h(ReadOutlined, { style: { color: '#1890FF' } }), 'Design Guide'),
    description: 'How to design a good product?',
    children: [
      {
        key: '2-1',
        icon: h(HeartOutlined),
        description: `Know the well`,
      },
      {
        key: '2-2',
        icon: h(SmileOutlined),
        description: `Set the AI role`,
      },
      {
        key: '2-3',
        icon: h(CommentOutlined),
        description: `Express the feeling`,
      },
    ],
  },
]

const senderPromptsItems: PromptsProps['items'] = [
  {
    key: '1',
    description: 'Hot Topics',
    icon: h(FireOutlined, { style: { color: '#FF4D4F' } }),
  },
  {
    key: '2',
    description: 'Design Guide',
    icon: h(ReadOutlined, { style: { color: '#1890FF' } }),
  },
]

const roles: BubbleListProps['roles'] = {
  ai: {
    placement: 'start',
    typing: { step: 5, interval: 20 },
    styles: {
      content: {
        borderRadius: '16px',
      },
    },
  },
  local: {
    placement: 'end',
    variant: 'shadow',
  },
}

const placeholderNode = computed(() => h(
  Space,
  { direction: "vertical", size: 16, style: styles.value.placeholder },
  () => [
    h(
      Welcome,
      {
        variant: "borderless",
        icon: "https://mdn.alipayobjects.com/huamei_iwk9zp/afts/img/A*s5sNRo5LjfQAAAAAAAAAAAAADgCCAQ/fmt.webp",
        title: "Hello, I'm Ant Design X",
        description: "Base on Ant Design, AGI product interface solution, create a better intelligent vision~",
        extra: h(Space, {}, () => [h(Button, { icon: h(ShareAltOutlined) }), h(Button, { icon: h(EllipsisOutlined) })]),
      }
    ),
    h(
      Prompts,
      {
        title: "Do you want?",
        items: placeholderPromptsItems,
        styles: {
          list: {
            width: '100%',
          },
          item: {
            flex: 1,
          },
        },
        onItemClick: handlePromptsItemClick,
      }
    )
  ]
))

const items = computed<BubbleListProps['items']>(() => {
  if (props.messages.length === 0) {
    return [{ content: placeholderNode, variant: 'borderless' }]
  }
  return props.messages.map(({ id, message, status }) => ({
    key: id,
    loading: status === 'loading',
    role: status === 'local' ? 'local' : 'ai',
    content: message,
  }))
})

const handleSubmit = (content: string) => {
  emit('submit', content)
}

const handleChange = (value: string) => {
  emit('change', value)
}

function handlePromptsItemClick(info: any) {
  emit('promptClick', info.data.description as string)
}

const handleSenderPromptsItemClick: PromptsProps['onItemClick'] = (info) => {
  emit('promptClick', info.data.description as string)
}
</script>

<template>
  <div :style="styles.chat">
    <!-- 消息列表 -->
    <Bubble.List
      :items="items"
      :roles="roles"
      :style="styles.messages"
    />

    <!-- 提示词 -->
    <Prompts
      :items="senderPromptsItems"
      @item-click="handleSenderPromptsItemClick"
    />

    <!-- 输入框 -->
    <ChatInput
      :value="props.content"
      :loading="props.loading"
      @submit="handleSubmit"
      @change="handleChange"
    />
  </div>
</template>